home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_amanda.idb / usr / freeware / libexec / amplot.awk.z / amplot.awk
Encoding:
AWK Script  |  1999-07-16  |  15.3 KB  |  442 lines

  1. #
  2. # Amanda, The Advanced Maryland Automatic Network Disk Archiver
  3. # Copyright (c) 1992-1998 University of Maryland at College Park
  4. # All Rights Reserved.
  5. #
  6. # Permission to use, copy, modify, distribute, and sell this software and its
  7. # documentation for any purpose is hereby granted without fee, provided that
  8. # the above copyright notice appear in all copies and that both that
  9. # copyright notice and this permission notice appear in supporting
  10. # documentation, and that the name of U.M. not be used in advertising or
  11. # publicity pertaining to distribution of the software without specific,
  12. # written prior permission.  U.M. makes no representations about the
  13. # suitability of this software for any purpose.  It is provided "as is"
  14. # without express or implied warranty.
  15. #
  16. # U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
  18. # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19. # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20. # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  21. # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22. #
  23. # Author: Olafur Gudumundsson, ogud@tis.com
  24. # formerly at:     Systems Design and Analysis Group
  25. #           Computer Science Department
  26. #           University of Maryland at College Park
  27. #
  28. # An awk program to parse the amdump file and output the information
  29. # in a form at the gnuplot program amplot.g wants
  30. #
  31. #    Creation Date: April 1992
  32. #    modified: Aug 1993
  33. #       Modified for Amanda-2.2: Dec 1993
  34. #       Modified for Amanda-2.2: Mar 1994 and May 1994 and June 1994
  35. #       Enhanced: April 1995
  36. #    Input: One amdump file 
  37. #    Output: Number of files that get fed into gnuplot
  38. #
  39. BEGIN{
  40. # The folowing parameters may have to be set to suit each site, both 
  41. # parameters are expressed in HOUR's. 
  42. # If your average amanda dump is more than 3 hours you should increase the
  43. # value of maxtime, similary if your dumps are finishing in less than 2 hours
  44. # you should decrease the value of maxtime.
  45. # This is now setable from amplot's command line.
  46. #    maxtime  = 4;            # how long to plot graph for in hours
  47.  
  48. # Min host controls the reporting of hosts that take long in dumping
  49. # This varible can be set explicity or as a fraction of maxtime
  50. # If you are seeing too many hosts reported increase the value of this 
  51. # constant
  52. #
  53.     min_host = maxtime * 0.75;    # good rule of thumb
  54. #    min_host = 2.5;            # expicit cutoff value in hours
  55.  
  56. #
  57. # DO NOT CHANGE ANYTHING BELOW THIS LINE
  58. #
  59.     time_scale = 60;    # display in minutes DO NOT CHANGE
  60.     maxtime  *= time_scale  # convert to minutes
  61.     min_host *= time_scale *time_scale; # convert to seconds
  62.                                                 # dumping than this 
  63.         disk_raise = 120;    # scaling factors for Holding disk graph
  64.         tape_raise = 90;
  65.     dump_shift = 7.5;    # scaling factors for Dumpers idle graph
  66.     dump_raise = 0;
  67.     que_raise  = 300;    # scaling factors for the queue's
  68.     count_scale= 1.0/3.0;    # new scale 
  69.                 # scaling factors for the x axis 
  70.     bandw_raise = 250;
  71.     bandw_scale = 30/300;   # default calculated below 
  72.  
  73.     holding_disk = -1;      # uninitialized
  74.         
  75.     cnt        = 0;        # default values for counters
  76.     din        = 0;        # number of dumps to holding disk
  77.     dout       = 0;     # number of dumps to tape 
  78.     tapeq       = 0;        # how many dumps in tape queue
  79.     tape_err   = 0;        # how many tape errors
  80.     tout       = 0;        # data written out to tape 
  81.     quit       = 0;        # normal end of run
  82.     plot_fmt   = "%7.2f %6.2f\n%7.2f %6.2f\n";  # format of files for gnuplot
  83. }
  84.     
  85. {        # state machine for processing input lines lines
  86.     if( $1 == "driver:") {
  87.         if($2=="result")            do_result();
  88.         else if( $2=="state")       do_state();
  89.         else if( $2=="interface-state") ;
  90.         else if( $2=="hdisk-state") do_hdisk++;
  91.         else if( $2=="start")       do_start();
  92.         else if( $2=="send-cmd") { 
  93.             if( $7=="FILE-DUMP"){
  94.               file_dump++;
  95.               dmpr_strt[$6]=$4;
  96.               host[$6]=$10;
  97.               disk[$6]=$11;
  98.               level[$6]=$12;
  99.             }
  100.             else if( $7 == "FILE-WRITE") file_write++;
  101.             else if( $7 == "START-TAPER") fil = $8;
  102.         }
  103.         else if( $2=="finished-cmd") cmd_fin++;
  104.         else if ($2=="started")      forked++;
  105.         else if( $2=="QUITTING")     do_quit();
  106.         else if( $2=="dumping" || $2 == "adding" || $2 == "holding-disks:") 
  107.           dumping++; # eat this line
  108.         else if( $2!="FINISHED" && $2 != "pid" && $2 != "taper-tryagain")
  109.           print fil,"Unknown statement#",$0;
  110.     }
  111.     else if ( $1 == "planner:") {
  112.         if( $2 == "SKIPPED" || $2 == "FAILED") {
  113.             failed++;
  114.             print fil, "INFO#", $0;
  115.         }
  116.     }
  117.     else if( $1 == "GENERATING")        sched_start=NR;
  118.     else if( $1 == "DELAYING")          do_moves();    # find estimated size
  119.     else if( $1 == "dumper:" && $4 != "starting" && $2 !="pid") 
  120.                 print fil, "INFO#", $0;
  121.     else if( $1 == "taper:" && $3 != "label" && $3 != "end" && $2 != "DONE"\
  122.          && $2 != "pid" && $2 != "slot" && $2 != "reader-side:")  print fil, "INFO#", $0;
  123.     else if( $1 == "planner:")          print fil, "INFO#", $0;
  124.     else if( NF==1 && sched_start > 0 && NR-sched_start > 1) { # new style end of schedule
  125.         no_disks = NR-sched_start-2; # lets hope there are no extra lines
  126.         sched_start = 0;
  127.     }
  128. }
  129.  
  130. function do_state(){        # state line is printed out after driver
  131.                 # finishes pondering new actions
  132.                 # it reports the state as seen be driver
  133. # fields in the state line 
  134. # $2 = "state"         # $3 = "time"         # $4 = time_val
  135. # $5 = "free"        # $6 = "kps:"        # $7 =  free_kps
  136. # $8 = "space:"        # $9 = space        # $10 = "taper:"
  137. # $11 = "writing"/"idle"# $12 = "idle-dumpers:"
  138. # $13 = #idle         # $14 = "qlen"        # $15 = "tapeq:"
  139. # $16 = #waiting    # $17 = "runq:"        # $18 = #not started 
  140. # $19 = "stoppedq:"    # $20 = #stopped
  141.  
  142.     cnt++;                    # number of event
  143.     time = $4/time_scale;
  144.     unused = (bandw - $7)*bandw_scale+bandw_raise;
  145.     if( unused != unused_old) 
  146.         printf plot_fmt, time, unused_old, time,unused >>"bandw_free";
  147.     unused_old = unused;
  148.  
  149.     space = (holding_disk - $9)*const+disk_raise;    # how much disk is used
  150.     if( space != space_old ) 
  151.         printf plot_fmt, time, space_old, time, space >> "disk_alloc";
  152.     space_old = space;
  153.  
  154.     twait = tsize*const+disk_raise;
  155.     if( twait != twait_old )
  156.         printf plot_fmt, time, twait_old, time, twait >> "tape_wait";
  157.     twait_old = twait;
  158.  
  159.     active = (dumpers-$13)*dump_shift+dump_raise;
  160.     if( active != active_old )
  161.         printf plot_fmt, time, active_old, time, active >> "dump_idle";
  162.     active_old = active;
  163.  
  164. # tape on or off
  165.     if($11=="writing")state = tape_raise+10;
  166.     else              state = tape_raise;
  167.     if( state != state_old )
  168.         printf plot_fmt, time, state_old, time, state >> "tape_idle";
  169.     state_old = state;
  170.  
  171.     run = $18*count_scale+que_raise;
  172.     if( run != run_old )
  173.         printf plot_fmt, time, run_old, time, run >> "run_queue";
  174.     run_old = run;
  175.  
  176.     finish = written * count_scale+que_raise;
  177.     if( finish != finish_old )
  178.         printf plot_fmt, time, finish_old, time, finish >> "finished";
  179.     finish_old = finish;
  180.  
  181.     tapeQ = $16 * count_scale+que_raise;
  182.     if( tapeQ != tapeQ_old )
  183.         printf plot_fmt, time, tapeQ_old, time, tapeQ >> "tape_queue";
  184.     tapeQ_old = tapeQ;
  185.  
  186. }
  187.  
  188. function do_start() {         # get configuration parameters
  189.     dumpers    = $6;    # how many 
  190.     day        = $14;
  191.     dump_shift = 75/dumpers; 
  192.     bandw      = $8;        
  193.     bandw_scale = (30/bandw);
  194.     unused_old = bandw_raise;
  195.     print 0, unused_old > "bandw_free";
  196.     if( sched_start >0 ) {
  197.         no_disks = NR-sched_start-1; # backward compatability
  198.         sched_start =0;
  199.         print "do_start: no_disks", no_disks, $0;
  200.     }
  201.     size        = $10/1024;           # size of holding disk in MB
  202.     holding_disk= $10;    
  203.     if (holding_disk != 0) {
  204.         const        = 100/holding_disk; # displaying the use of the holding disk
  205.     } else {
  206.         const        = 100;
  207.     }
  208.     space_old    = twait_old = disk_raise;
  209.     print 0, space_old > "disk_alloc"; # need to reset the files I create 
  210.     print 0, twait_old > "tape_wait"; # need to reset the files I create 
  211.     if( NF==14) {        # original file was missing this
  212.         policy="FIFO";
  213.         alg   ="InOrder";
  214.     }
  215.     else if(NF>=18) {        # newer files have this format
  216.         policy = $18;
  217.         alg = $16;
  218.         if( alg=="drain-ends") big = $20; 
  219.     }
  220.     
  221.     start = $4;    # this is the start time of the first dump 
  222.             # taper idle to this point should not be included
  223.     run_old = no_disks*cont_scale+que_raise;
  224.     print 0, run_old        >"run_queue";
  225.     finish_old = tapeQ_old = que_raise;
  226.     print 0, finish_old        >"finished";     
  227.     print 0, tapeQ_old        >"tape_queue" ;    
  228.     state_old = tape_raise;
  229.     print 0, state_old         > "tape_idle";
  230.     active_old = dump_raise;
  231.     print 0,active_old         >"dump_idle";
  232.  
  233. }
  234.  
  235. function do_quit(){        # this is issued by driver at the end
  236.                 # when it has nothing more to do
  237.     cnt++;
  238.     quit = 1;
  239.     tim  = $4 / time_scale;
  240.     printf plot_fmt, tim, space_old, tim, space_old >>"disk_alloc";
  241.     printf plot_fmt, tim, twait_old, tim, disk_raise >>"tape_wait";
  242.     printf plot_fmt, tim, active_old, tim, dump_raise >>"dump_idle";
  243.     printf plot_fmt, tim, state_old, tim, tape_raise >>"tape_idle";    
  244.     printf plot_fmt, tim, unused_old, tim, bandw_raise >>"bandw_free";
  245.     printf plot_fmt, tim, finish_old, tim, written*count_scale+que_raise >>"finished";
  246.     printf plot_fmt, tim, run_old, tim, run_old >>"run_queue";
  247. }
  248.  
  249. function do_result(){        # process lines driver: result
  250.     if($7=="DONE" ) {
  251.         if( $6=="taper:"){         # taper done
  252.             tsize -= $12;    
  253.             tout  += $12;
  254.             tcnt--;    written++;
  255.         }
  256.         else {                 # dumperx done 
  257.           tsize += (int($12/32)+1)*32;     # in tape blocks 
  258.           tcnt++;    done++;
  259.           xx = host[$6];
  260.           d = disk[$6];
  261.           l = level[$6];
  262.           host_time[xx]+= ( tt = $4 - dmpr_strt[$6]);
  263.           if(xx in disk_list) disk_list[xx] = disk_list[xx] "\n";
  264.           disk_list[xx] = disk_list[xx] \
  265.                   xx ":" d "/" l "\t" \
  266.                   pr_time(dmpr_strt[$6]) \
  267.                   " - " pr_time($4) \
  268.                   " = "  pr_time(tt);
  269. #          print host[$6], disk[host[$6]];
  270. #            print host[$6], $4, dmpr_strt[$6], host_time[host[$6]]
  271.         }
  272.     }
  273.     else if ($6=="taper:") {        # something else than DONE
  274.         if($7=="TAPE-ERROR") {
  275.             tape_err= 1;
  276.             err_time=$4/time_scale;
  277.         }
  278.         else if ($7=="TAPER-OK") tape_err=0;
  279.         else if ($7=="PORT")    tape_err=0;
  280.         else print fil, "UNKNOWN STATUS# "$0 ;
  281.     }
  282.     else {                     # something bad from dumper 
  283.         if ($7=="FAILED") { failed++;}
  284.         else if ($7=="TRY-AGAIN"){ try++;}
  285.         else if ($7=="NO-ROOM")  
  286.           print fil, pr_time($4),"#"  ++no_room, $0;
  287.         else if( $7=="ABORT-FINISHED") print fil, "#" ++no_abort, $0;
  288.         else print fil, "UNKNOWN STATUS# " $0;
  289.     }
  290. }
  291.  
  292. function do_moves() { # function that extracts the estimated size of dumps
  293.               # by processing DELAYING and promoting lines
  294.     est_size=$6;
  295.     getline ;            # eat get next line print out planner msg
  296.     while (NF > 0 && (($1 == "delay:") || ($1 == "planner:")) ) {
  297.       if( $1 == "delay:") est_size = $NF;     # processing delay lines
  298.       else print fil, "DELAY#", $0;
  299.       getline;
  300.     }
  301.     getline ;             # eating blank line
  302.     if( $1== "PROMOTING") {         # everything is dandy 
  303.         getline;        # get first promote line
  304.         while ( NF>0 && (($1 == "promote:")|| ($1 =="planner:")) ) {
  305.             if( $2 == "moving") est_size=$8;
  306.             else if($2 != "checking" && $2 != "can't" && $3 != "too")
  307.                  print fil,"PROMOTING#", $0;
  308.             getline ;    # get next promote line
  309.         }
  310.     }
  311.     else print fil, "DID NOT FIND PROMOTING LINE IN THE RIGHT PLACE",NR,$0;
  312. }
  313.  
  314.  
  315. END {
  316.     if( holding_disk == -1) {         # bad input file 
  317.         print fil,": MISSING SPACE DECLARATION" ;
  318.         exit;
  319.     }
  320. # print headers of each graph  this is for the gnulot version 
  321.     if( tim >maxtime && extend==0)# if graph will extend beond borders
  322.       printf "Graph extends beond borders %s taking %7.3f > (max = %7.3f)\n",
  323.             fil, tim, maxtime ;
  324.     print_t();            # print titles
  325.     if( no_room + no_abort > 0) 
  326.          printf "NO-ROOM=%5d ABORT-FINISHED=%5d\n",  no_room, no_abort;
  327.     max_out = 20;
  328.     old_t = min_host * min_host;  # Some thing big
  329.     print "Longest dumping hosts   Times", min_host;
  330.     print "Host:disk/lev  \t start  -   end   =   run\t=> total";
  331.     while ( max_out-- > 0 && old_t > min_host) {
  332.       t = 0;
  333.       for (j in host_time) {
  334.         if( t < host_time[j] && host_time[j] <old_t){
  335.           t = host_time[d=j];
  336.         }
  337.       }
  338.       printf "%s\t=> %s\n\n", disk_list[d], pr_time(host_time[d]);
  339. #      printf "%-20.20s Total Dump time %s\n", d, pr_time(host_time[d]);
  340.       old_t = t;
  341.     }
  342. }
  343.  
  344. function print_t(){        # printing out the labels for the graph 
  345.     label=0;        # calculating where labels go and 
  346.                 # range for x and y axes
  347.     maxy = int(no_disks/60+1)*20+que_raise;
  348.     printf "set yrange[0:%d]\n",maxy >"title";
  349.     if( maxtime < tim && extend !=0) {
  350.         printf "set xrange[0:%d]\n", tim+30 >>"title";
  351.         second_col = tim*0.5;
  352.         key_col = tim;
  353.         third_col = tim +13;
  354.     }
  355.     else {
  356.         printf "set xrange[0:%d]\n", maxtime >>"title";
  357.         second_col = (maxtime-10) * 0.5;
  358.         key_col = (maxtime-10) ;
  359.         third_col = maxtime +3;
  360.     }
  361.     label_shift = (7 + int(no_disks/100));
  362.     lab = label_start = maxy+(6*label_shift) ;  # showing 6 labels
  363.     printf "set key %d, %d\n", key_col, lab >>"title";
  364.     printf "set label %d \"Amanda Dump %s\" at 10,%d\n", ++label,fil, 
  365.         lab >"title";
  366.     lab -= label_shift;
  367.     printf "set label %d \"Bandwidth = %d\" at 10,%d\n",++label,bandw,
  368.         lab >>"title";
  369.  
  370.     lab -= label_shift;
  371.     printf "set label %d \"Holding disk = %d\" at 10,%d\n",++label,size,
  372.         lab >>"title";
  373.  
  374.     lab -= label_shift;
  375.     printf "set label %d \"Tape Policy = %s\" at 10,%d\n",++label,policy,
  376.         lab >>"title";
  377.  
  378.     lab -= label_shift;
  379.     printf "set label %d \"Dumpers= %d\" at 10,%d\n",++label,dumpers,
  380.         lab >>"title";
  381.  
  382.     lab -= label_shift;
  383.     if( alg =="drain-ends") 
  384.         printf "set label %d \"Driver alg = %s At big end %d\" at 10,%d\n",
  385.             ++label,alg, big,lab >>"title";
  386.     else #if( alg =="InOrder")  # other special cases
  387.         printf "set label %d \"Driver alg = %s\" at 10,%d\n",
  388.             ++label,alg, lab >>"title";
  389.  
  390.     lab = label_start;
  391.     printf "set label %d \"Elapsed Time = %s\" at %d,%d\n",
  392.         ++label,pr_time(tim*60),second_col,lab >>"title";
  393.  
  394.     lab -= label_shift;
  395.     if( tape_err==1)    stm = "TAPE ERROR";
  396.     else if( quit ==1)    stm = "SUCCESS";
  397.     else  {            stm = "UNKNOWN";
  398.         print "Unknown terminating status",fil;
  399.     }
  400.     printf "set label %d \"Final status = %s\" at %d,%d\n",
  401.         ++label,stm, second_col,lab >> "title";
  402.  
  403.     lab -= label_shift;
  404.     printf "set label %d \"Dumped/Failed = %3d/%d\" at %d,%d\n",
  405.         ++label,done,(failed+(try/2)), second_col,lab >>"title";
  406.  
  407.     lab -= label_shift; 
  408.     printf "set label %d \"Output data size = %d\" at %d, %d\n",
  409.         ++label,int(tout/1024+0.49999),second_col,lab >>"title";
  410.     if( est_size >0) {
  411.         lab -= label_shift; 
  412.         printf "set label %d \"Estimated data size = %d\" at %d, %d\n",
  413.             ++label,int(est_size/1024+0.49999),second_col,lab >>"title";
  414.     }
  415.  
  416.     if (gnuplot==0) {
  417.         printf "set output \"%s.ps\"\n",fil >>"title";
  418.         if(paper==1) printf "set term postscript landscape \"Times-Roman\" 10\n" >>"title";
  419.         else printf "set term postscript portrait \"Times-Roman\" 10\n" >>"title";
  420.     }
  421.     printf "set ylabel """";" >>"title";     # make sure there is no ylabel
  422.     fmt= "set label %d \"%s\" at "third_col", %d\n";
  423.     printf fmt, ++label,"%DUMPERS", 40 >>"title";
  424.     printf fmt, ++label,"TAPE",  95 >>"title";
  425.     printf fmt, ++label,"HOLDING",180 >>"title";
  426.     printf fmt, ++label,"DISK", 160 >>"title";
  427.     printf fmt, ++label,"%BANDWIDTH", 260 >>"title";
  428.     printf fmt, ++label,"QUEUES",(que_raise+maxy)/2 >>"title";
  429.     if((paper+gnuplot) > 0)    print "set size 0.9, 0.9;"  >>"title";
  430.     else            print "set size 0.7,1.3;"   >>"title";
  431. }
  432.  
  433. function pr_time(pr_a){ #function to pretty print time
  434.   pr_h = int(pr_a/3600);
  435.   pr_m = int(pr_a/60)%60;
  436.   pr_s = int(pr_a+0.5) %60;
  437.   if( pr_m < 10 && pr_s < 10 ) return  pr_h":0"pr_m":0"pr_s;
  438.   else if( pr_s < 10)          return  pr_h":" pr_m":0"pr_s;
  439.   else if( pr_m < 10)          return  pr_h":0"pr_m":" pr_s;
  440.   else                         return  pr_h":" pr_m":" pr_s;
  441. }
  442.